package com.bibimaya.auto.mapper.dao.registry;

import com.bibimaya.auto.mapper.dao.annotation.EnableAutoMapper;
import com.bibimaya.auto.mapper.dao.mapper.AutoMapperAware;
import com.bibimaya.auto.mapper.dao.scan.ClassScaner;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * EnableConfigRegistry
 * create by lijianwei
 * 2018-12-6
 */
public class EnableAutoMapperRegistry implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        Map<String, Object> defaultAttrs =
                metadata.getAnnotationAttributes(EnableAutoMapper.class.getName(), true);
        String[] mapperPackages = ((String[])defaultAttrs.get("mapperPackages"));
        String basePackage = ((StandardAnnotationMetadata) metadata).getIntrospectedClass().getPackage().getName();
        if(mapperPackages == null || mapperPackages.length == 0){
            mapperPackages = new String[]{basePackage};
        }
        String defaultMapperSuffix = (String) defaultAttrs.get("defaultMapperSuffix");
        String defaultEntitySuffix = (String) defaultAttrs.get("defaultEntitySuffix");
        BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(AutoMapperAware.class);
        definitionBuilder.addPropertyValue("mapperList", getMappers(mapperPackages));
        definitionBuilder.addPropertyValue("defaultMapperSuffix", defaultMapperSuffix);
        definitionBuilder.addPropertyValue("defaultEntitySuffix", defaultEntitySuffix);
        registry.registerBeanDefinition("autoMapper", definitionBuilder.getBeanDefinition());
    }

    private List<String> getMappers(String[] packages){
        List<String> mapperList = new ArrayList<>();
        if(packages != null && packages.length > 0) {
            for(String p : packages) {
                Set<Class<?>> classSet = ClassScaner.getClass(p, true);
                if (classSet == null || classSet.isEmpty()) {
                    continue;
                }
                for (Class c : classSet) {
                    if (c.isAnnotationPresent(Mapper.class)) {
                        mapperList.add(c.getCanonicalName());
                    }
                }
            }
        }
        return mapperList;
    }

}
